﻿using SQLRunnerLib.Util;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using SQLRunnerLib.Project;
using System.IO;
using SQLRunnerLib.Exceptions;
namespace SQLUnitTests
{
    
    
    /// <summary>
    ///This is a test class for LineControllerTest and is intended
    ///to contain all LineControllerTest Unit Tests
    ///</summary>
    [TestClass()]
    public class LineControllerTest
        :TestBase
    {

        private SQLProject project;
        private string projectPath;

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get { return testContextInstance; }
            set { testContextInstance = value; }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        [TestInitialize()]
        public void MyTestInitialize()
        {
            project = CreateTestProjectWithEnvironment();
            // Can't used AppDomain.CurrentDomain.BaseDirectory due to bug.  See http://frazzleddad.blogspot.com/2008/06/test-execution-problem-in-vs2008.html
            projectPath = Path.Combine(System.Environment.CurrentDirectory, @"project.sqlrunner");
            CreateTestProjectWithEnvironment().Serialize(projectPath);
        }
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion


        /// <summary>
        ///A test for ValidateArgs where the project argument is not supplied.
        ///</summary>
        [TestMethod()]
        [DeploymentItem("SQLRunnerLib.dll")]
        [ExpectedException(typeof(ValidationException))]
        public void ValidateArgsWithMissingProjectTest()
        {
            // The LineController_Accessor allows us to test private members of LineController.
            LineController_Accessor lineController = new LineController_Accessor();
            string[] args = new string[] { "-s:lineServer", "-d:lineDB", "-u:username", "-w:pwd" };
            LineParser lineParser = new LineParser(args);
        }

        [TestMethod()]
        [DeploymentItem("SQLRunnerLib.dll")]
        public void ValidateArgsWithMissingTrustedTest()
        {
        }

        [TestMethod()]
        [DeploymentItem("SQLRunnerLib.dll")]
        public void ValidateArgsWithTest()
        {
        }

        [TestMethod()]
        [DeploymentItem("SQLRunnerLib.dll")]
        public void ValidateArgs()
        {
        }

        /// <summary>
        /// Test where project not provided
        /// </summary>
        [TestMethod()]
        [DeploymentItem("SQLRunnerLib.dll")]
        [ExpectedException(typeof(ValidationException))]
        public void StartWithMissingProjectArgTest()
        {
            LineController_Accessor lineController = new LineController_Accessor();
            string[] args = new string[] { "-s:lineServer", "-d:lineDB", "-u:username", "-w:pwd" };
            LineParser lineParser = new LineParser(args);
            lineController.Start(lineParser);
        }

        //Test where only help arg provided

        //Test where project arg provided but file does not exist
        //Test where project arg provided but file not a project file
        //Test where project arg provided but folder section empty
        
        /// <summary>
        /// Test where project arg provided but environment section empty and no connection info supplied
        /// </summary>
        [TestMethod()]
        [DeploymentItem("SQLRunnerLib.dll")]
        public void ValidateArgsWithMissingEnvironmentTest()
        {
            string projectPathArg = "-p:" + projectPath;
            LineController_Accessor lineController = new LineController_Accessor();
            string[] args = new string[] {projectPathArg };
            LineParser lineParser = new LineParser(args);
        }

        [TestMethod]
        public void BuildEnvironmentWithNoExtraArgsSuppliedTest()
        {
            string projectPath = CreateProjectFile(CreateTestProjectWithEnvironment(), @"project.sqlrunner");

            string projectPathArg = "-p:" + projectPath;
            string[] args = new string[] { projectPathArg, "-v:test" };
            LineParser lineParser = new LineParser(args);
            LineController_Accessor lineController = new LineController_Accessor();
            lineController.BuildEnvironment(lineParser);

            Assert.AreEqual("test", lineParser.Environment.Name);
            Assert.AreEqual("serverName", lineParser.Environment.ServerName);
            Assert.AreEqual("dbName", lineParser.Environment.DatabaseName);
            Assert.IsNull(lineParser.Environment.Username);
            Assert.AreEqual(string.Empty, lineParser.Environment.Password);
            Assert.AreEqual(AuthenticationType.WindowsAuthentication, lineParser.Environment.Authentication);
        }

        [TestMethod]
        public void BuildEnvironmentWithDBNameArgTest()
        {
            string projectPath = CreateProjectFile(CreateTestProjectWithEnvironment(), @"project.sqlrunner");

            string projectPathArg = "-p:" + projectPath;
            string[] args = new string[] { projectPathArg, "-v:test", "-d:lineDB" };
            LineParser lineParser = new LineParser(args);
            LineController_Accessor lineController = new LineController_Accessor();
            lineController.BuildEnvironment(lineParser);

            Assert.AreEqual("test", lineParser.Environment.Name);
            Assert.AreEqual("serverName", lineParser.Environment.ServerName);
            Assert.AreEqual("lineDB", lineParser.Environment.DatabaseName);
            Assert.IsNull(lineParser.Environment.Username);
            Assert.AreEqual(string.Empty,lineParser.Environment.Password);
            Assert.AreEqual(AuthenticationType.WindowsAuthentication, lineParser.Environment.Authentication);
        }

        [TestMethod]
        public void BuildEnvironmentWithExtraArgsSuppliedTest()
        {
            string projectPath = CreateProjectFile(CreateTestProjectWithEnvironment(), @"project.sqlrunner");

            string projectPathArg = "-p:" + projectPath;
            string[] args = new string[] { projectPathArg, "-v:test", "-s:lineServer", "-u:username", "-w:pwd" };
            LineParser lineParser = new LineParser(args);
            LineController_Accessor lineController = new LineController_Accessor();
            lineController.BuildEnvironment(lineParser);

            Assert.AreEqual("test", lineParser.Environment.Name);
            Assert.AreEqual("lineServer", lineParser.Environment.ServerName);
            Assert.AreEqual("dbName", lineParser.Environment.DatabaseName);
            Assert.AreEqual("username", lineParser.Environment.Username);
            Assert.AreEqual("pwd", lineParser.Environment.Password);
            Assert.AreEqual(AuthenticationType.SQLServerAuthentication, lineParser.Environment.Authentication);
        }

        [TestMethod]
        public void BuildEnvironmentWithoutEnvironmentArg()
        {
            string projectPath = CreateProjectFile(CreateTestProjectWithEnvironment(), @"project.sqlrunner");

            string projectPathArg = "-p:" + projectPath;
            string[] args = new string[] { projectPathArg, "-s:lineServer", "-d:lineDB", "-u:username", "-w:pwd" };
            LineParser lineParser = new LineParser(args);
            LineController_Accessor lineController = new LineController_Accessor();
            lineController.BuildEnvironment(lineParser);

            Assert.AreEqual("CommandLine", lineParser.Environment.Name);
            Assert.AreEqual("lineServer", lineParser.Environment.ServerName);
            Assert.AreEqual("lineDB", lineParser.Environment.DatabaseName);
            Assert.AreEqual("username", lineParser.Environment.Username);
            Assert.AreEqual("pwd", lineParser.Environment.Password);
            Assert.AreEqual(AuthenticationType.SQLServerAuthentication, lineParser.Environment.Authentication);
        }

        //Test where project arg provided but environment section empty and no server provided
        //Test where project arg provided but environment section empty and no database provided
        
        //Test where project arg provided but environment section empty, not trusted, no username, no password
        //Test where project arg provided but environment section empty, not trusted, no username
        //Test where project arg provided but environment section empty, not trusted, no password

        //Test where project arg provided, environment section exists but not used and no connection info supplied
        //Test where project arg provided, environment section exists but not used.

        //Test where project arg provided, environment exists and is used. Environment: Valid.
        //Test where project arg provided, environment exists and is used. Environment: DB not found.
        //Test where project arg provided, environment exists and is used. Environment: Server not found.
        //Test where project arg provided, environment exists and is used. Environment: Credentials don't work.
    }
}
